//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension Route53RecoveryControlConfig {
    // MARK: Enums

    public enum RuleType: String, CustomStringConvertible, Codable, _SotoSendable {
        case and = "AND"
        case atleast = "ATLEAST"
        case or = "OR"
        public var description: String { return self.rawValue }
    }

    public enum Status: String, CustomStringConvertible, Codable, _SotoSendable {
        case deployed = "DEPLOYED"
        case pending = "PENDING"
        case pendingDeletion = "PENDING_DELETION"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AssertionRule: AWSDecodableShape {
        /// The routing controls that are part of transactions that are evaluated to determine if a request to change a routing control state is allowed. For example, you might include three routing controls, one for each of three Amazon Web Services Regions.
        public let assertedControls: [String]
        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String
        /// Name of the assertion rule. You can use any non-white space character in the name.
        public let name: String
        /// The criteria that you set for specific assertion routing controls (AssertedControls) that designate how many routing control states must be ON as the result of a transaction. For example, if you have three assertion routing controls, you might specify ATLEAST 2 for your rule configuration. This means that at least two assertion routing control states must be ON, so that at least two Amazon Web Services Regions have traffic flowing to them.
        public let ruleConfig: RuleConfig
        /// The Amazon Resource Name (ARN) of the assertion rule.
        public let safetyRuleArn: String
        /// The deployment status of an assertion rule. Status can be one of the following: PENDING, DEPLOYED, PENDING_DELETION.
        public let status: Status
        /// An evaluation period, in milliseconds (ms), during which any request against the target routing controls will fail. This helps prevent "flapping" of state. The wait period is 5000 ms by default, but you can choose a custom value.
        public let waitPeriodMs: Int

        public init(assertedControls: [String], controlPanelArn: String, name: String, ruleConfig: RuleConfig, safetyRuleArn: String, status: Status, waitPeriodMs: Int) {
            self.assertedControls = assertedControls
            self.controlPanelArn = controlPanelArn
            self.name = name
            self.ruleConfig = ruleConfig
            self.safetyRuleArn = safetyRuleArn
            self.status = status
            self.waitPeriodMs = waitPeriodMs
        }

        private enum CodingKeys: String, CodingKey {
            case assertedControls = "AssertedControls"
            case controlPanelArn = "ControlPanelArn"
            case name = "Name"
            case ruleConfig = "RuleConfig"
            case safetyRuleArn = "SafetyRuleArn"
            case status = "Status"
            case waitPeriodMs = "WaitPeriodMs"
        }
    }

    public struct AssertionRuleUpdate: AWSEncodableShape {
        /// The name of the assertion rule. You can use any non-white space character in the name.
        public let name: String
        /// The Amazon Resource Name (ARN) of the assertion rule.
        public let safetyRuleArn: String
        /// An evaluation period, in milliseconds (ms), during which any request against the target routing controls will fail. This helps prevent "flapping" of state. The wait period is 5000 ms by default, but you can choose a custom value.
        public let waitPeriodMs: Int

        public init(name: String, safetyRuleArn: String, waitPeriodMs: Int = 0) {
            self.name = name
            self.safetyRuleArn = safetyRuleArn
            self.waitPeriodMs = waitPeriodMs
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^\\S+$")
            try self.validate(self.safetyRuleArn, name: "safetyRuleArn", parent: name, max: 256)
            try self.validate(self.safetyRuleArn, name: "safetyRuleArn", parent: name, min: 1)
            try self.validate(self.safetyRuleArn, name: "safetyRuleArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case safetyRuleArn = "SafetyRuleArn"
            case waitPeriodMs = "WaitPeriodMs"
        }
    }

    public struct Cluster: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the cluster.
        public let clusterArn: String?
        /// Endpoints for a cluster. Specify one of these endpoints when you want to set or retrieve a routing control state in the cluster. To get or update the routing control state, see the Amazon Route 53 Application Recovery Controller Routing Control Actions.
        public let clusterEndpoints: [ClusterEndpoint]?
        /// The name of the cluster.
        public let name: String?
        /// Deployment status of a resource. Status can be one of the following: PENDING, DEPLOYED, PENDING_DELETION.
        public let status: Status?

        public init(clusterArn: String? = nil, clusterEndpoints: [ClusterEndpoint]? = nil, name: String? = nil, status: Status? = nil) {
            self.clusterArn = clusterArn
            self.clusterEndpoints = clusterEndpoints
            self.name = name
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case clusterArn = "ClusterArn"
            case clusterEndpoints = "ClusterEndpoints"
            case name = "Name"
            case status = "Status"
        }
    }

    public struct ClusterEndpoint: AWSDecodableShape {
        /// A cluster endpoint. Specify an endpoint and Amazon Web Services Region when you want to set or retrieve a routing control state in the cluster. To get or update the routing control state, see the Amazon Route 53 Application Recovery Controller Routing Control Actions.
        public let endpoint: String?
        /// The Amazon Web Services Region for a cluster endpoint.
        public let region: String?

        public init(endpoint: String? = nil, region: String? = nil) {
            self.endpoint = endpoint
            self.region = region
        }

        private enum CodingKeys: String, CodingKey {
            case endpoint = "Endpoint"
            case region = "Region"
        }
    }

    public struct ControlPanel: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the cluster that includes the control panel.
        public let clusterArn: String?
        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String?
        /// A flag that Amazon Route 53 Application Recovery Controller sets to true to designate the default control panel for a cluster. When you create a cluster, Amazon Route 53 Application Recovery Controller creates a control panel, and sets this flag for that control panel. If you create a control panel yourself, this flag is set to false.
        public let defaultControlPanel: Bool?
        /// The name of the control panel. You can use any non-white space character in the name.
        public let name: String?
        /// The number of routing controls in the control panel.
        public let routingControlCount: Int?
        /// The deployment status of control panel. Status can be one of the following: PENDING, DEPLOYED, PENDING_DELETION.
        public let status: Status?

        public init(clusterArn: String? = nil, controlPanelArn: String? = nil, defaultControlPanel: Bool? = nil, name: String? = nil, routingControlCount: Int? = nil, status: Status? = nil) {
            self.clusterArn = clusterArn
            self.controlPanelArn = controlPanelArn
            self.defaultControlPanel = defaultControlPanel
            self.name = name
            self.routingControlCount = routingControlCount
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case clusterArn = "ClusterArn"
            case controlPanelArn = "ControlPanelArn"
            case defaultControlPanel = "DefaultControlPanel"
            case name = "Name"
            case routingControlCount = "RoutingControlCount"
            case status = "Status"
        }
    }

    public struct CreateClusterRequest: AWSEncodableShape {
        /// A unique, case-sensitive string of up to 64 ASCII characters. To make an idempotent API request with an action, specify a client token in the request.
        public let clientToken: String?
        /// The name of the cluster.
        public let clusterName: String
        /// The tags associated with the cluster.
        public let tags: [String: String]?

        public init(clientToken: String? = CreateClusterRequest.idempotencyToken(), clusterName: String, tags: [String: String]? = nil) {
            self.clientToken = clientToken
            self.clusterName = clusterName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^\\S+$")
            try self.validate(self.clusterName, name: "clusterName", parent: name, max: 64)
            try self.validate(self.clusterName, name: "clusterName", parent: name, min: 1)
            try self.validate(self.clusterName, name: "clusterName", parent: name, pattern: "^\\S+$")
            try self.tags?.forEach {
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^\\S+$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case clusterName = "ClusterName"
            case tags = "Tags"
        }
    }

    public struct CreateClusterResponse: AWSDecodableShape {
        /// The cluster that was created.
        public let cluster: Cluster?

        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct CreateControlPanelRequest: AWSEncodableShape {
        /// A unique, case-sensitive string of up to 64 ASCII characters. To make an idempotent API request with an action, specify a client token in the request.
        public let clientToken: String?
        /// The Amazon Resource Name (ARN) of the cluster for the control panel.
        public let clusterArn: String
        /// The name of the control panel.
        public let controlPanelName: String
        /// The tags associated with the control panel.
        public let tags: [String: String]?

        public init(clientToken: String? = CreateControlPanelRequest.idempotencyToken(), clusterArn: String, controlPanelName: String, tags: [String: String]? = nil) {
            self.clientToken = clientToken
            self.clusterArn = clusterArn
            self.controlPanelName = controlPanelName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^\\S+$")
            try self.validate(self.clusterArn, name: "clusterArn", parent: name, max: 256)
            try self.validate(self.clusterArn, name: "clusterArn", parent: name, min: 1)
            try self.validate(self.clusterArn, name: "clusterArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            try self.validate(self.controlPanelName, name: "controlPanelName", parent: name, max: 64)
            try self.validate(self.controlPanelName, name: "controlPanelName", parent: name, min: 1)
            try self.validate(self.controlPanelName, name: "controlPanelName", parent: name, pattern: "^\\S+$")
            try self.tags?.forEach {
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^\\S+$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case clusterArn = "ClusterArn"
            case controlPanelName = "ControlPanelName"
            case tags = "Tags"
        }
    }

    public struct CreateControlPanelResponse: AWSDecodableShape {
        /// Information about a control panel.
        public let controlPanel: ControlPanel?

        public init(controlPanel: ControlPanel? = nil) {
            self.controlPanel = controlPanel
        }

        private enum CodingKeys: String, CodingKey {
            case controlPanel = "ControlPanel"
        }
    }

    public struct CreateRoutingControlRequest: AWSEncodableShape {
        /// A unique, case-sensitive string of up to 64 ASCII characters. To make an idempotent API request with an action, specify a client token in the request.
        public let clientToken: String?
        /// The Amazon Resource Name (ARN) of the cluster that includes the routing control.
        public let clusterArn: String
        /// The Amazon Resource Name (ARN) of the control panel that includes the routing control.
        public let controlPanelArn: String?
        /// The name of the routing control.
        public let routingControlName: String

        public init(clientToken: String? = CreateRoutingControlRequest.idempotencyToken(), clusterArn: String, controlPanelArn: String? = nil, routingControlName: String) {
            self.clientToken = clientToken
            self.clusterArn = clusterArn
            self.controlPanelArn = controlPanelArn
            self.routingControlName = routingControlName
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^\\S+$")
            try self.validate(self.clusterArn, name: "clusterArn", parent: name, max: 256)
            try self.validate(self.clusterArn, name: "clusterArn", parent: name, min: 1)
            try self.validate(self.clusterArn, name: "clusterArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, max: 256)
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, min: 1)
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            try self.validate(self.routingControlName, name: "routingControlName", parent: name, max: 64)
            try self.validate(self.routingControlName, name: "routingControlName", parent: name, min: 1)
            try self.validate(self.routingControlName, name: "routingControlName", parent: name, pattern: "^\\S+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case clusterArn = "ClusterArn"
            case controlPanelArn = "ControlPanelArn"
            case routingControlName = "RoutingControlName"
        }
    }

    public struct CreateRoutingControlResponse: AWSDecodableShape {
        /// The routing control that is created.
        public let routingControl: RoutingControl?

        public init(routingControl: RoutingControl? = nil) {
            self.routingControl = routingControl
        }

        private enum CodingKeys: String, CodingKey {
            case routingControl = "RoutingControl"
        }
    }

    public struct CreateSafetyRuleRequest: AWSEncodableShape {
        /// The assertion rule requested.
        public let assertionRule: NewAssertionRule?
        /// A unique, case-sensitive string of up to 64 ASCII characters. To make an idempotent API request with an action, specify a client token in the request.
        public let clientToken: String?
        /// The gating rule requested.
        public let gatingRule: NewGatingRule?
        /// The tags associated with the safety rule.
        public let tags: [String: String]?

        public init(assertionRule: NewAssertionRule? = nil, clientToken: String? = CreateSafetyRuleRequest.idempotencyToken(), gatingRule: NewGatingRule? = nil, tags: [String: String]? = nil) {
            self.assertionRule = assertionRule
            self.clientToken = clientToken
            self.gatingRule = gatingRule
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.assertionRule?.validate(name: "\(name).assertionRule")
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^\\S+$")
            try self.gatingRule?.validate(name: "\(name).gatingRule")
            try self.tags?.forEach {
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^\\S+$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case assertionRule = "AssertionRule"
            case clientToken = "ClientToken"
            case gatingRule = "GatingRule"
            case tags = "Tags"
        }
    }

    public struct CreateSafetyRuleResponse: AWSDecodableShape {
        /// The assertion rule created.
        public let assertionRule: AssertionRule?
        /// The gating rule created.
        public let gatingRule: GatingRule?

        public init(assertionRule: AssertionRule? = nil, gatingRule: GatingRule? = nil) {
            self.assertionRule = assertionRule
            self.gatingRule = gatingRule
        }

        private enum CodingKeys: String, CodingKey {
            case assertionRule = "AssertionRule"
            case gatingRule = "GatingRule"
        }
    }

    public struct DeleteClusterRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "clusterArn", location: .uri("ClusterArn"))
        ]

        /// The Amazon Resource Name (ARN) of the cluster that you're deleting.
        public let clusterArn: String

        public init(clusterArn: String) {
            self.clusterArn = clusterArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteClusterResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteControlPanelRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "controlPanelArn", location: .uri("ControlPanelArn"))
        ]

        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String

        public init(controlPanelArn: String) {
            self.controlPanelArn = controlPanelArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteControlPanelResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteRoutingControlRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "routingControlArn", location: .uri("RoutingControlArn"))
        ]

        /// The Amazon Resource Name (ARN) of the routing control that you're deleting.
        public let routingControlArn: String

        public init(routingControlArn: String) {
            self.routingControlArn = routingControlArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteRoutingControlResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteSafetyRuleRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "safetyRuleArn", location: .uri("SafetyRuleArn"))
        ]

        /// The ARN of the safety rule.
        public let safetyRuleArn: String

        public init(safetyRuleArn: String) {
            self.safetyRuleArn = safetyRuleArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteSafetyRuleResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DescribeClusterRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "clusterArn", location: .uri("ClusterArn"))
        ]

        /// The Amazon Resource Name (ARN) of the cluster.
        public let clusterArn: String

        public init(clusterArn: String) {
            self.clusterArn = clusterArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeClusterResponse: AWSDecodableShape {
        /// The cluster for the DescribeCluster request.
        public let cluster: Cluster?

        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct DescribeControlPanelRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "controlPanelArn", location: .uri("ControlPanelArn"))
        ]

        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String

        public init(controlPanelArn: String) {
            self.controlPanelArn = controlPanelArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeControlPanelResponse: AWSDecodableShape {
        /// Information about the control panel.
        public let controlPanel: ControlPanel?

        public init(controlPanel: ControlPanel? = nil) {
            self.controlPanel = controlPanel
        }

        private enum CodingKeys: String, CodingKey {
            case controlPanel = "ControlPanel"
        }
    }

    public struct DescribeRoutingControlRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "routingControlArn", location: .uri("RoutingControlArn"))
        ]

        /// The Amazon Resource Name (ARN) of the routing control.
        public let routingControlArn: String

        public init(routingControlArn: String) {
            self.routingControlArn = routingControlArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeRoutingControlResponse: AWSDecodableShape {
        /// Information about the routing control.
        public let routingControl: RoutingControl?

        public init(routingControl: RoutingControl? = nil) {
            self.routingControl = routingControl
        }

        private enum CodingKeys: String, CodingKey {
            case routingControl = "RoutingControl"
        }
    }

    public struct DescribeSafetyRuleRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "safetyRuleArn", location: .uri("SafetyRuleArn"))
        ]

        /// The ARN of the safety rule.
        public let safetyRuleArn: String

        public init(safetyRuleArn: String) {
            self.safetyRuleArn = safetyRuleArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeSafetyRuleResponse: AWSDecodableShape {
        /// The assertion rule in the response.
        public let assertionRule: AssertionRule?
        /// The gating rule in the response.
        public let gatingRule: GatingRule?

        public init(assertionRule: AssertionRule? = nil, gatingRule: GatingRule? = nil) {
            self.assertionRule = assertionRule
            self.gatingRule = gatingRule
        }

        private enum CodingKeys: String, CodingKey {
            case assertionRule = "AssertionRule"
            case gatingRule = "GatingRule"
        }
    }

    public struct GatingRule: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String
        /// An array of gating routing control Amazon Resource Names (ARNs). For a simple "on/off" switch, specify the ARN for one routing control. The gating routing controls are evaluated by the rule configuration that you specify to determine if the target routing control states can be changed.
        public let gatingControls: [String]
        /// The name for the gating rule. You can use any non-white space character in the name.
        public let name: String
        /// The criteria that you set for gating routing controls that designate how many of the routing control states must be ON to allow you to update target routing control states.
        public let ruleConfig: RuleConfig
        /// The Amazon Resource Name (ARN) of the gating rule.
        public let safetyRuleArn: String
        /// The deployment status of a gating rule. Status can be one of the following: PENDING, DEPLOYED, PENDING_DELETION.
        public let status: Status
        /// An array of target routing control Amazon Resource Names (ARNs) for which the states can only be updated if the rule configuration that you specify evaluates to true for the gating routing control. As a simple example, if you have a single gating control, it acts as an overall "on/off" switch for a set of target routing controls. You can use this to manually override automated failover, for example.
        public let targetControls: [String]
        /// An evaluation period, in milliseconds (ms), during which any request against the target routing controls will fail. This helps prevent "flapping" of state. The wait period is 5000 ms by default, but you can choose a custom value.
        public let waitPeriodMs: Int

        public init(controlPanelArn: String, gatingControls: [String], name: String, ruleConfig: RuleConfig, safetyRuleArn: String, status: Status, targetControls: [String], waitPeriodMs: Int) {
            self.controlPanelArn = controlPanelArn
            self.gatingControls = gatingControls
            self.name = name
            self.ruleConfig = ruleConfig
            self.safetyRuleArn = safetyRuleArn
            self.status = status
            self.targetControls = targetControls
            self.waitPeriodMs = waitPeriodMs
        }

        private enum CodingKeys: String, CodingKey {
            case controlPanelArn = "ControlPanelArn"
            case gatingControls = "GatingControls"
            case name = "Name"
            case ruleConfig = "RuleConfig"
            case safetyRuleArn = "SafetyRuleArn"
            case status = "Status"
            case targetControls = "TargetControls"
            case waitPeriodMs = "WaitPeriodMs"
        }
    }

    public struct GatingRuleUpdate: AWSEncodableShape {
        /// The name for the gating rule. You can use any non-white space character in the name.
        public let name: String
        /// The Amazon Resource Name (ARN) of the gating rule.
        public let safetyRuleArn: String
        /// An evaluation period, in milliseconds (ms), during which any request against the target routing controls will fail. This helps prevent "flapping" of state. The wait period is 5000 ms by default, but you can choose a custom value.
        public let waitPeriodMs: Int

        public init(name: String, safetyRuleArn: String, waitPeriodMs: Int = 0) {
            self.name = name
            self.safetyRuleArn = safetyRuleArn
            self.waitPeriodMs = waitPeriodMs
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^\\S+$")
            try self.validate(self.safetyRuleArn, name: "safetyRuleArn", parent: name, max: 256)
            try self.validate(self.safetyRuleArn, name: "safetyRuleArn", parent: name, min: 1)
            try self.validate(self.safetyRuleArn, name: "safetyRuleArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case safetyRuleArn = "SafetyRuleArn"
            case waitPeriodMs = "WaitPeriodMs"
        }
    }

    public struct ListAssociatedRoute53HealthChecksRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("MaxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("NextToken")),
            AWSMemberEncoding(label: "routingControlArn", location: .uri("RoutingControlArn"))
        ]

        /// The number of objects that you want to return with this call.
        public let maxResults: Int?
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of the routing control.
        public let routingControlArn: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, routingControlArn: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.routingControlArn = routingControlArn
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListAssociatedRoute53HealthChecksResponse: AWSDecodableShape {
        /// Identifiers for the health checks.
        public let healthCheckIds: [String]?
        /// Next token for listing health checks.
        public let nextToken: String?

        public init(healthCheckIds: [String]? = nil, nextToken: String? = nil) {
            self.healthCheckIds = healthCheckIds
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case healthCheckIds = "HealthCheckIds"
            case nextToken = "NextToken"
        }
    }

    public struct ListClustersRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("MaxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("NextToken"))
        ]

        /// The number of objects that you want to return with this call.
        public let maxResults: Int?
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListClustersResponse: AWSDecodableShape {
        /// An array of the clusters in an account.
        public let clusters: [Cluster]?
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?

        public init(clusters: [Cluster]? = nil, nextToken: String? = nil) {
            self.clusters = clusters
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case clusters = "Clusters"
            case nextToken = "NextToken"
        }
    }

    public struct ListControlPanelsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "clusterArn", location: .querystring("ClusterArn")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("MaxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("NextToken"))
        ]

        /// The Amazon Resource Name (ARN) of a cluster.
        public let clusterArn: String?
        /// The number of objects that you want to return with this call.
        public let maxResults: Int?
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?

        public init(clusterArn: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.clusterArn = clusterArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListControlPanelsResponse: AWSDecodableShape {
        /// The result of a successful ListControlPanel request.
        public let controlPanels: [ControlPanel]?
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?

        public init(controlPanels: [ControlPanel]? = nil, nextToken: String? = nil) {
            self.controlPanels = controlPanels
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case controlPanels = "ControlPanels"
            case nextToken = "NextToken"
        }
    }

    public struct ListRoutingControlsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "controlPanelArn", location: .uri("ControlPanelArn")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("MaxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("NextToken"))
        ]

        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String
        /// The number of objects that you want to return with this call.
        public let maxResults: Int?
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?

        public init(controlPanelArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.controlPanelArn = controlPanelArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListRoutingControlsResponse: AWSDecodableShape {
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?
        /// An array of routing controls.
        public let routingControls: [RoutingControl]?

        public init(nextToken: String? = nil, routingControls: [RoutingControl]? = nil) {
            self.nextToken = nextToken
            self.routingControls = routingControls
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case routingControls = "RoutingControls"
        }
    }

    public struct ListSafetyRulesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "controlPanelArn", location: .uri("ControlPanelArn")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("MaxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("NextToken"))
        ]

        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String
        /// The number of objects that you want to return with this call.
        public let maxResults: Int?
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?

        public init(controlPanelArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.controlPanelArn = controlPanelArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListSafetyRulesResponse: AWSDecodableShape {
        /// The token that identifies which batch of results you want to see.
        public let nextToken: String?
        /// The list of safety rules in a control panel.
        public let safetyRules: [Rule]?

        public init(nextToken: String? = nil, safetyRules: [Rule]? = nil) {
            self.nextToken = nextToken
            self.safetyRules = safetyRules
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case safetyRules = "SafetyRules"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn"))
        ]

        /// The Amazon Resource Name (ARN) for the resource that's tagged.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The tags associated with the resource.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct NewAssertionRule: AWSEncodableShape {
        /// The routing controls that are part of transactions that are evaluated to determine if a request to change a routing control state is allowed. For example, you might include three routing controls, one for each of three Amazon Web Services Regions.
        public let assertedControls: [String]
        /// The Amazon Resource Name (ARN) for the control panel.
        public let controlPanelArn: String
        /// The name of the assertion rule. You can use any non-white space character in the name.
        public let name: String
        /// The criteria that you set for specific assertion controls (routing controls) that designate how many control states must be ON as the result of a transaction. For example, if you have three assertion controls, you might specify ATLEAST 2 for your rule configuration. This means that at least two assertion controls must be ON, so that at least two Amazon Web Services Regions have traffic flowing to them.
        public let ruleConfig: RuleConfig
        /// An evaluation period, in milliseconds (ms), during which any request against the target routing controls will fail. This helps prevent "flapping" of state. The wait period is 5000 ms by default, but you can choose a custom value.
        public let waitPeriodMs: Int

        public init(assertedControls: [String], controlPanelArn: String, name: String, ruleConfig: RuleConfig, waitPeriodMs: Int = 0) {
            self.assertedControls = assertedControls
            self.controlPanelArn = controlPanelArn
            self.name = name
            self.ruleConfig = ruleConfig
            self.waitPeriodMs = waitPeriodMs
        }

        public func validate(name: String) throws {
            try self.assertedControls.forEach {
                try validate($0, name: "assertedControls[]", parent: name, max: 256)
                try validate($0, name: "assertedControls[]", parent: name, min: 1)
                try validate($0, name: "assertedControls[]", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            }
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, max: 256)
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, min: 1)
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^\\S+$")
        }

        private enum CodingKeys: String, CodingKey {
            case assertedControls = "AssertedControls"
            case controlPanelArn = "ControlPanelArn"
            case name = "Name"
            case ruleConfig = "RuleConfig"
            case waitPeriodMs = "WaitPeriodMs"
        }
    }

    public struct NewGatingRule: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String
        /// The gating controls for the new gating rule. That is, routing controls that are evaluated by the rule configuration that you specify.
        public let gatingControls: [String]
        /// The name for the new gating rule.
        public let name: String
        /// The criteria that you set for specific gating controls (routing controls) that designate how many control states must be ON to allow you to change (set or unset) the target control states.
        public let ruleConfig: RuleConfig
        /// Routing controls that can only be set or unset if the specified RuleConfig evaluates to true for the specified GatingControls. For example, say you have three gating controls, one for each of three Amazon Web Services Regions. Now you specify ATLEAST 2 as your RuleConfig. With these settings, you can only change (set or unset) the routing controls that you have specified as TargetControls if that rule evaluates to true. In other words, your ability to change the routing controls that you have specified as TargetControls is gated by the rule that you set for the routing controls in GatingControls.
        public let targetControls: [String]
        /// An evaluation period, in milliseconds (ms), during which any request against the target routing controls will fail. This helps prevent "flapping" of state. The wait period is 5000 ms by default, but you can choose a custom value.
        public let waitPeriodMs: Int

        public init(controlPanelArn: String, gatingControls: [String], name: String, ruleConfig: RuleConfig, targetControls: [String], waitPeriodMs: Int = 0) {
            self.controlPanelArn = controlPanelArn
            self.gatingControls = gatingControls
            self.name = name
            self.ruleConfig = ruleConfig
            self.targetControls = targetControls
            self.waitPeriodMs = waitPeriodMs
        }

        public func validate(name: String) throws {
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, max: 256)
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, min: 1)
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            try self.gatingControls.forEach {
                try validate($0, name: "gatingControls[]", parent: name, max: 256)
                try validate($0, name: "gatingControls[]", parent: name, min: 1)
                try validate($0, name: "gatingControls[]", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            }
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^\\S+$")
            try self.targetControls.forEach {
                try validate($0, name: "targetControls[]", parent: name, max: 256)
                try validate($0, name: "targetControls[]", parent: name, min: 1)
                try validate($0, name: "targetControls[]", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case controlPanelArn = "ControlPanelArn"
            case gatingControls = "GatingControls"
            case name = "Name"
            case ruleConfig = "RuleConfig"
            case targetControls = "TargetControls"
            case waitPeriodMs = "WaitPeriodMs"
        }
    }

    public struct RoutingControl: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the control panel that includes the routing control.
        public let controlPanelArn: String?
        /// The name of the routing control.
        public let name: String?
        /// The Amazon Resource Name (ARN) of the routing control.
        public let routingControlArn: String?
        /// The deployment status of a routing control. Status can be one of the following: PENDING, DEPLOYED, PENDING_DELETION.
        public let status: Status?

        public init(controlPanelArn: String? = nil, name: String? = nil, routingControlArn: String? = nil, status: Status? = nil) {
            self.controlPanelArn = controlPanelArn
            self.name = name
            self.routingControlArn = routingControlArn
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case controlPanelArn = "ControlPanelArn"
            case name = "Name"
            case routingControlArn = "RoutingControlArn"
            case status = "Status"
        }
    }

    public struct Rule: AWSDecodableShape {
        /// An assertion rule enforces that, when a routing control state is changed, the criteria set by the rule configuration is met. Otherwise, the change to the routing control state is not accepted. For example, the criteria might be that at least one routing control state is On after the transaction so that traffic continues to flow to at least one cell for the application. This ensures that you avoid a fail-open scenario.
        public let assertion: AssertionRule?
        /// A gating rule verifies that a gating routing control or set of gating routing controls, evaluates as true, based on a rule configuration that you specify, which allows a set of routing control state changes to complete. For example, if you specify one gating routing control and you set the Type in the rule configuration to OR, that indicates that you must set the gating routing control to On for the rule to evaluate as true; that is, for the gating control "switch" to be "On". When you do that, then you can update the routing control states for the target routing controls that you specify in the gating rule.
        public let gating: GatingRule?

        public init(assertion: AssertionRule? = nil, gating: GatingRule? = nil) {
            self.assertion = assertion
            self.gating = gating
        }

        private enum CodingKeys: String, CodingKey {
            case assertion = "ASSERTION"
            case gating = "GATING"
        }
    }

    public struct RuleConfig: AWSEncodableShape & AWSDecodableShape {
        /// Logical negation of the rule. If the rule would usually evaluate true, it's evaluated as false, and vice versa.
        public let inverted: Bool
        /// The value of N, when you specify an ATLEAST rule type. That is, Threshold is the number of controls that must be set when you specify an ATLEAST type.
        public let threshold: Int
        /// A rule can be one of the following: ATLEAST, AND, or OR.
        public let type: RuleType

        public init(inverted: Bool, threshold: Int, type: RuleType) {
            self.inverted = inverted
            self.threshold = threshold
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case inverted = "Inverted"
            case threshold = "Threshold"
            case type = "Type"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn"))
        ]

        /// The Amazon Resource Name (ARN) for the resource that's tagged.
        public let resourceArn: String
        /// The tags associated with the resource.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.tags.forEach {
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^\\S+$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("ResourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring("TagKeys"))
        ]

        /// The Amazon Resource Name (ARN) for the resource that's tagged.
        public let resourceArn: String
        /// Keys for the tags to be removed.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateControlPanelRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the control panel.
        public let controlPanelArn: String
        /// The name of the control panel.
        public let controlPanelName: String

        public init(controlPanelArn: String, controlPanelName: String) {
            self.controlPanelArn = controlPanelArn
            self.controlPanelName = controlPanelName
        }

        public func validate(name: String) throws {
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, max: 256)
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, min: 1)
            try self.validate(self.controlPanelArn, name: "controlPanelArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            try self.validate(self.controlPanelName, name: "controlPanelName", parent: name, max: 64)
            try self.validate(self.controlPanelName, name: "controlPanelName", parent: name, min: 1)
            try self.validate(self.controlPanelName, name: "controlPanelName", parent: name, pattern: "^\\S+$")
        }

        private enum CodingKeys: String, CodingKey {
            case controlPanelArn = "ControlPanelArn"
            case controlPanelName = "ControlPanelName"
        }
    }

    public struct UpdateControlPanelResponse: AWSDecodableShape {
        /// The control panel to update.
        public let controlPanel: ControlPanel?

        public init(controlPanel: ControlPanel? = nil) {
            self.controlPanel = controlPanel
        }

        private enum CodingKeys: String, CodingKey {
            case controlPanel = "ControlPanel"
        }
    }

    public struct UpdateRoutingControlRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the routing control.
        public let routingControlArn: String
        /// The name of the routing control.
        public let routingControlName: String

        public init(routingControlArn: String, routingControlName: String) {
            self.routingControlArn = routingControlArn
            self.routingControlName = routingControlName
        }

        public func validate(name: String) throws {
            try self.validate(self.routingControlArn, name: "routingControlArn", parent: name, max: 256)
            try self.validate(self.routingControlArn, name: "routingControlArn", parent: name, min: 1)
            try self.validate(self.routingControlArn, name: "routingControlArn", parent: name, pattern: "^[A-Za-z0-9:\\/_-]*$")
            try self.validate(self.routingControlName, name: "routingControlName", parent: name, max: 64)
            try self.validate(self.routingControlName, name: "routingControlName", parent: name, min: 1)
            try self.validate(self.routingControlName, name: "routingControlName", parent: name, pattern: "^\\S+$")
        }

        private enum CodingKeys: String, CodingKey {
            case routingControlArn = "RoutingControlArn"
            case routingControlName = "RoutingControlName"
        }
    }

    public struct UpdateRoutingControlResponse: AWSDecodableShape {
        /// The routing control that was updated.
        public let routingControl: RoutingControl?

        public init(routingControl: RoutingControl? = nil) {
            self.routingControl = routingControl
        }

        private enum CodingKeys: String, CodingKey {
            case routingControl = "RoutingControl"
        }
    }

    public struct UpdateSafetyRuleRequest: AWSEncodableShape {
        /// The assertion rule to update.
        public let assertionRuleUpdate: AssertionRuleUpdate?
        /// The gating rule to update.
        public let gatingRuleUpdate: GatingRuleUpdate?

        public init(assertionRuleUpdate: AssertionRuleUpdate? = nil, gatingRuleUpdate: GatingRuleUpdate? = nil) {
            self.assertionRuleUpdate = assertionRuleUpdate
            self.gatingRuleUpdate = gatingRuleUpdate
        }

        public func validate(name: String) throws {
            try self.assertionRuleUpdate?.validate(name: "\(name).assertionRuleUpdate")
            try self.gatingRuleUpdate?.validate(name: "\(name).gatingRuleUpdate")
        }

        private enum CodingKeys: String, CodingKey {
            case assertionRuleUpdate = "AssertionRuleUpdate"
            case gatingRuleUpdate = "GatingRuleUpdate"
        }
    }

    public struct UpdateSafetyRuleResponse: AWSDecodableShape {
        /// The assertion rule updated.
        public let assertionRule: AssertionRule?
        /// The gating rule updated.
        public let gatingRule: GatingRule?

        public init(assertionRule: AssertionRule? = nil, gatingRule: GatingRule? = nil) {
            self.assertionRule = assertionRule
            self.gatingRule = gatingRule
        }

        private enum CodingKeys: String, CodingKey {
            case assertionRule = "AssertionRule"
            case gatingRule = "GatingRule"
        }
    }
}

// MARK: - Errors

/// Error enum for Route53RecoveryControlConfig
public struct Route53RecoveryControlConfigErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Route53RecoveryControlConfig
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// 403 response - You do not have sufficient access to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// 409 response - ConflictException. You might be using a predefined variable.
    public static var conflictException: Self { .init(.conflictException) }
    /// 500 response - InternalServiceError. Temporary service error. Retry the request.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// 404 response - MalformedQueryString. The query string contains a syntax error or resource not found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// 402 response - You attempted to create more resources than the service allows based on service quotas.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// 429 response - LimitExceededException or TooManyRequestsException.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// 400 response - Multiple causes. For example, you might have a malformed query string and input parameter might be out of range, or you might have used parameters together incorrectly.
    public static var validationException: Self { .init(.validationException) }
}

extension Route53RecoveryControlConfigErrorType: Equatable {
    public static func == (lhs: Route53RecoveryControlConfigErrorType, rhs: Route53RecoveryControlConfigErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension Route53RecoveryControlConfigErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
